// torch includes
#include <torch/script.h> // One-stop header.
#include <torch/torch.h>

// frame includes
#include "athread.h"
#include <QTime>
#include <QDebug>
#include <QMutex>
#include <QFileDialog>


// c++ includes
#include <math.h>
#include <memory>
#include <string>
#include <vector>
#include <fstream>
#include <dirent.h>
#include <iostream>
#include <sys/time.h>

// OPENCV includes
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>


MyThread::MyThread() {
    this_lv_struct_.begin_dcm =0 ;
    this_lv_struct_.sum_dcm =0 ;
    this_lv_struct_.begin_array=0 ;
    this_lv_struct_.gpu=0;
}

void MyThread::SetLStruct(int tmp_begin_dcm,
                          int tmp_sum_dcm,
                          int tmp_begin_array,
                          int tmp_gpu,
                          double *tmp_testshortarr,
                          vtkSmartPointer<vtkImageData> tmp_imagedata_) {
    this_lv_struct_.begin_dcm =tmp_begin_dcm ;
    this_lv_struct_.sum_dcm =tmp_sum_dcm ;
    this_lv_struct_.begin_array=tmp_begin_array ;
    this_lv_struct_.gpu=tmp_gpu;
    this_lv_struct_.testshortarr=tmp_testshortarr;
    this_lv_struct_.imagedata->DeepCopy(tmp_imagedata_);
}

void MyThread::run() {
    cv::Mat img;
    img.create(512, 512, CV_32FC1);
    torch::DeviceType device_type;
    device_type = torch::kCUDA;
    torch::jit::script::Module module0 =
            torch::jit::load("/home/dell/文档/QT_work/LeftVentricle/bin/torch_script_gpu.pt");
    torch::Device device0(device_type, static_cast<short>(
                              this_lv_struct_.gpu));
    module0.to(device0);
    torch::cuda::is_available();
    at::TensorOptions options(at::kFloat);
    for (int dcm = 0; dcm < this_lv_struct_.sum_dcm / 5; ++dcm) {
        at::Tensor pred = torch::zeros({5, 512, 512});
        for (int i = 0; i < 5; i++) {
            for (int nr = 0; nr < 512; nr++) {
                float *outData = img.ptr<float>(nr);
                for (int mc = 0; mc < 512 ; mc++) {
                    float *pixel = static_cast<float * >
                            (this_lv_struct_.imagedata->GetScalarPointer(
                                 mc, nr, this_lv_struct_.begin_dcm + dcm * 5 + i));
                    outData[mc] = *pixel;
                }
            }
            at::Tensor tensor_image = torch::from_blob(img.data,
            { 1, 512, 512, 1 }, options);
            tensor_image = tensor_image.permute({ 0, 3, 1, 2 }).to(device0);
            pred[i] = module0.forward({tensor_image}).toTensor()[0][0];
        }
        for (int i = 0; i < 5; i++) {
            at::Tensor pred_00 = pred[i];
            for (int w = 0; w < 512; ++w) {
                at::Tensor pred_000 = pred_00[w];
                for (int jj = 0; jj < 512; jj++) {
                    at::Tensor pred_0000 = pred_000[jj];
                    this_lv_struct_.testshortarr[
                            512 * w + jj + i * 262144 +
                            dcm * 262144 * 5 + this_lv_struct_.begin_array]
                            = 255 * (*(pred_0000.data<float>()) > 0.5);
                }
            }
        }
    }
    emit SignalThreadEnd();
}




























